package com.xishu.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.geo.GeoRadiusParam;

import java.util.List;
import java.util.Set;

public class JRedisUtil {
    private static Logger logger = LoggerFactory.getLogger(JRedisUtil.class);

    private static RedisCachePool pool = RedisCachePool.getInstance();

    /**
     * 获取hash表中所有key
     *
     * @param name
     * @return
     */
    public static Set<String> getHashAllKey(String name) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.hkeys(name);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }

    /**
     * 从redis hash表中获取
     *
     * @param hashName
     * @param key
     * @return
     */
    public static String getHashKV(String hashName, String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.hget(hashName, key);
        } catch (Exception e) {
            logger.error("", e);
            ;
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }

    /**
     * 删除hash表的键值对
     *
     * @param hashName
     * @param key
     */
    public static Long delHashKV(String hashName, String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.hdel(hashName, key);
        } catch (Exception e) {
            logger.error("", e);
            ;
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }

    /**
     * 存放hash表键值对
     *
     * @param hashName
     * @param key
     * @param value
     */
    public static Long setHashKV(String hashName, String key, String value) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.hset(hashName, key, value);
        } catch (Exception e) {
            logger.error("", e);
            ;
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }

    /**
     * 删除键值对
     *
     * @param k
     * @return
     */
    public static Long delKV(String k) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.del(k);
        } catch (Exception e) {
            logger.error("", e);
            ;
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }

    /**
     * 放键值对
     * 永久
     *
     * @param k
     * @param v
     */
    public static String setKV(String k, Long v) {
        return setKV(k, String.valueOf(v));
    }

    /**
     * 放键值对
     * 永久
     *
     * @param k
     * @param v
     */
    public static String setKV(String k, String v) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.set(k, v);
        } catch (Exception e) {
            logger.error("", e);
            ;
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }


    /**
     * 放键值对
     *
     * @param k
     * @param v
     */
    public static String setKV(String k, int second, String v) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.setex(k, second, v);
        } catch (Exception e) {
            logger.error("", e);
            ;
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }

    /**
     * 根据key取value
     *
     * @param k
     * @return
     */
    public static String getKV(String k) {
        Jedis jedis = null;
        long startTime = System.currentTimeMillis();
        try {
            jedis = pool.getConnection();
            logger.info("get the pool costTime {}", System.currentTimeMillis() - startTime);
            return jedis.get(k);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            logger.info("get kv costTime {}", System.currentTimeMillis() - startTime);
            pool.returnConnection(jedis);
        }
        return null;
    }

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public static boolean expire(String key, int time) {
        Jedis jedis = null;

        try {
            if (time > 0) {
                jedis = pool.getConnection();
                jedis.expire(key, time);
            }
            return true;
        } catch (Exception e) {
            logger.error("", e);
            return false;
        } finally {
            pool.returnConnection(jedis);
        }

    }

    /**
     * 添加数据到SET里面
     *
     * @param key
     * @param value
     * @return
     */
    public static boolean addToSet(String key, String... value) {
        Jedis jedis = null;

        try {
            jedis = pool.getConnection();
            jedis.sadd(key, value);
            return true;
        } catch (Exception e) {
            logger.error("", e);
            return false;
        } finally {
            pool.returnConnection(jedis);
        }
    }

    /**
     * 获取set数据
     *
     * @param key
     * @return
     */
    public static Set<String> getSet(String key) {
        Jedis jedis = null;

        try {
            jedis = pool.getConnection();
            return jedis.smembers(key);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }

        return null;
    }

    /**
     * 设置某一个排序集合的值
     * 如果不存在则添加，返回值是1
     * 如果存在则更新，返回值是0
     * <p>
     * 如果报错了，返回值是2
     *
     * @param key
     * @param time
     * @param member
     * @return
     */
    public static long zadd(String key, Long time, String member) {
        Jedis jedis = null;

        try {
            jedis = pool.getConnection();
            return jedis.zadd(key, Double.parseDouble(time + ""), member);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }

        return 2;
    }

    /**
     * 获取集合中某一个值
     * 如果这个值不存在，那么返回null,不返回0，方便后续做处理
     *
     * @param key
     * @param member
     * @return
     */
    public static Double zscore(String key, String member) {
        Jedis jedis = null;

        try {
            jedis = pool.getConnection();
            return jedis.zscore(key, member);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }

        return null;
    }

    /**
     * 删除指定范围内的记录
     * <p>
     * 返回实际删除了多少条记录
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static long zremrangeByScore(final String key, final double start, final double end) {
        Jedis jedis = null;

        try {
            jedis = pool.getConnection();
            return jedis.zremrangeByScore(key, start, end);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }

        return -1;
    }

    /**
     * 返回实际多少条记录，如果KEY不存在，则返回0
     *
     * @param key
     * @return
     */
    public static long zcard(final String key) {
        Jedis jedis = null;

        try {
            jedis = pool.getConnection();
            return jedis.zcard(key);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }

        return 0;
    }

    /**
     * 向一个KEY里面自增1
     *
     * @param key
     * @return
     */
    public static long incr(final String key) {
        Jedis jedis = null;

        try {
            jedis = pool.getConnection();
            return jedis.incr(key);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }

        return 0;
    }


    /**
     * 判断这个key是否存在
     * @param k
     * @return
     */
    public static boolean exists(String k) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.exists(k);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }
        return false;
    }

    public static long addgeo(String key, double longitude, double latitude, String member) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.geoadd(key,longitude,latitude,member);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }
        return 0;
    }

    public static List<GeoCoordinate> getGeo(String key,  String member) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            return jedis.geopos(key,member);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }

    public static List<GeoRadiusResponse> getGeoRadius(String key, double longitude, double latitude, double radius) {
        Jedis jedis = null;
        try {
            jedis = pool.getConnection();
            GeoRadiusParam param = GeoRadiusParam.geoRadiusParam().withDist().withCoord().sortAscending();
            return jedis.georadius(key,longitude,latitude,radius, GeoUnit.KM,param);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            pool.returnConnection(jedis);
        }
        return null;
    }



}
